package dk.redia.digiform.utils;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.content.Context;
import android.content.IntentFilter;
import android.nfc.Tag;
import android.nfc.tech.NfcV;
import android.util.Log;
import dk.redia.digiform.utils.ScanResultListener;

public class NfcScanner implements IFScanner {

	private static final String logTag = "NfcScanner";
	private String[][] techLists;
	private IntentFilter[] filters;

	
	private Set<ScanResultListener> listeners;
	
	public NfcScanner(Context context) {
		listeners = new HashSet<ScanResultListener>();
		techLists = new String[][]{};
	}
	
	public IntentFilter[] getIntentFilter() {
		return filters;
	}
	
	public String[][] getTechList() {
		return techLists;
	}
	
	@Override
	public void addListener(ScanResultListener listener) {
		listeners.add(listener);
	}

	@Override
	public void removeListener(ScanResultListener listener) {
		listeners.remove(listener);
	}

	public void readNfcVTag(Tag tag) {
		NfcV v = NfcV.get(tag);
        try {
        	if(v != null) {
        		v.connect();
        		if(v.isConnected()) {
        			byte[] payload = v.transceive(new byte[]{0x00, 0x23, 0x00, 0x1C});
                	
                	if(payload != null) {
                		String data = new String(payload, Charset.forName("US-ASCII"));
                		Pattern p = Pattern.compile("([0-9]+)");
                		Matcher matcher = p.matcher(data);
                		if (matcher.find()) {
                			String result = new String(matcher.group(0));
                			notifyListenersScanned(result);
                		}
                	}
        		}
        	}
        } catch (IOException e) {
            Log.e(logTag, "IOException while reading tag", e);
            notifyListenersError();
            /*Toast readErrorToast = Toast.makeText(context, "IOException while reading tag", Toast.LENGTH_LONG);
            readErrorToast.setGravity(Gravity.CENTER, 0, 0);
            readErrorToast.show();*/
        } finally {
            if (v != null) {
               try {
                   v.close();
               }
               catch (IOException e) {
                   Log.e(logTag, "Error closing tag...", e);
               }
            }
        }
	}
	
	@Override
	public void run() {
	}
	
	private void notifyListenersDisconnected() {
		for (ScanResultListener listener : listeners) {
			listener.disconnected();
		}
	}
	
	private void notifyListenersScanned(String resourceId) {
		for (ScanResultListener listener : listeners) {
			listener.scanned(resourceId);
		}		
	}
	
	private void notifyListenersLog(String logTag, String msg) {
		for (ScanResultListener listener : listeners) {
			listener.log(msg);
		}	
	}
	
	private void notifyListenersError() {
		for (ScanResultListener listener : listeners) {
			listener.error();
		}
	}
}